package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.constant.TmsUrlConstant;
import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.framework.security.JwtAuthenicationFilter;
import cn.huiyunche.base.service.framework.utils.HYCUtils;
import cn.huiyunche.base.service.framework.utils.JdbcTemplateUtils;
import cn.huiyunche.base.service.framework.utils.QiniuUtils;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.mappers.ext.DUserViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.utils.DateUtils;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.driver.service.OrderService;
import cn.huiyunche.driver.service.TmsCustomerService;
import cn.huiyunche.driver.service.TmsRequestLogsService;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 客服服务层实现
 *
 * @author hdy [Tuffy]
 */
@Service
public class TmsCustomerServiceImpl implements TmsCustomerService {

    private static final Logger LOGGER = LoggerFactory.getLogger(TmsCustomerServiceImpl.class);

    /**
     * 中联客服登录缓存信息
     */
    private final String TMS_CUSTOMER_LOGIN_LIST = "TMS_CUSTOMER_LOGIN_LIST";
    /**
     * 中联客服登录缓存时效
     */
    private final int TIMER = 2 * 60 * 60 * 1000;
    private final String loginView = "tms/login";
    private final String indexView = "tms/index";

    /**
     * 错误登录返回码
     */
    private final String loginErrorCode = "99999";
    private final String default_password = "123456a";

    @Autowired
    private UserService userService = null;

    private UserService getUserService() {
        return this.userService;
    }

    @Autowired
    private DWaybillService dWaybillService = null;

    @Autowired
    private DWaybillStatusHistoryService dWaybillStatusHistoryService = null;

    @Autowired
    private TmsQueueService tmsQueueService = null;

    @Autowired
    private TmsOrderCallHistoryService tmsOrderCallHistoryService = null;

    @Autowired
    private OrderService orderService = null;

    @Autowired
    private TmsRequestLogsService tmsRequestLogsService = null;

    @Autowired
    private DUserExtMapper dUserExtMapper = null;

    @Autowired
    private DUserLicenseMapper dUserLicenseMapper = null;

    @Autowired
    private BLicenseTypeMapper bLicenseTypeMapper = null;

    @Autowired
    private DUserMapper dUserMapper = null;

    @Autowired
    private SUserMapper sUserMapper = null;

    @Autowired
    private DWaybillMapper dWaybillMapper = null;

    @Autowired
    private Md5PasswordEncoder passwordEncoder = null;

    @Autowired
    private JwtAuthenicationFilter jwtAuthenticationFilter = null;

    @Autowired
    private DUserViewMapper dUserViewMapper;


    /**
     * redis 连接对象
     */
    private Jedis jedis = null;

    @Override
    public Result<String> login(HttpServletRequest request, String phone, String password) {
        Result<String> r = new Result<>(true);
        List<Map<String, Object>> userList = JdbcTemplateUtils.getJdbcTemplate().queryForList("select username from sys_admin_user where username = '" + phone + "' and password = '" + password + "' and enabled = 'T'");
        if (null == userList || userList.size() <= 0) {
            r.setSuccess(false);
            r.setMessage("用户名或密码错误");
            return r;
        }
        try {
            jedis = HYCUtils.getJedis();
            // 成功返回
            this.append(request.getSession().getId());
        } finally {
            jedis.close();
        }
        r.setData(phone);
        return r;
    }

    @Override
    public Result<String> logout(HttpServletRequest request) {
        Result<String> result = new Result<>(true, "退出成功");
        try {
            jedis = HYCUtils.getJedis();
            this.remove(request.getSession().getId());
        } catch (Exception e) {
            LOGGER.error("zl logout error : {}.", e);
            throw new BusinessException("用户退出异常");
        } finally {
            jedis.close();
        }
        return result;
    }

    @Override
    public ModelAndView index(HttpServletRequest request) {
        ModelAndView mav = new ModelAndView(indexView);
        if (!this.isUsedCustomer(request)) {
            mav.setViewName(loginView);
            mav.addObject("errorMsg", "登录超时或已在其他设备上登录！");
        }
        return mav;
    }

    @Override
    public Result<String> cancelDWaybillWithUser(HttpServletRequest request, String orderCode, String cancelreason, String cancelflag) {
        LOGGER.info("cancelDWaybill param : orderCode-{}, cancelreason-{}, cancelflag-{}", orderCode, cancelreason, cancelflag);
        //验证用户
        Result<String> validationUser = this.validationUser(request);
        if (!validationUser.isSuccess()) {
            return validationUser;
        }
        Result<String> result = new Result<>(true, "取消成功！");
        if (StringUtils.isBlank(orderCode)) {
            LOGGER.error("cancelDWaybillWithUser param orderCode must not be null");
            throw new IllegalArgumentException("订单编号不能为空！");
        }
        try {
            DWaybill waybill = this.getByTmsOrderCode(orderCode, true);
            if (waybill.getUserId() <= 0) {
                result.setMessage("该订单还未分配或已取消");
                result.setSuccess(false);
                return result;
            }
            // 添加日志
            DRequestLogs drl = this.addLogs(orderCode, cancelreason, cancelflag);
            // 调用中联接口
            String errorText = this.cancelOrderByTms(cancelreason, cancelflag, waybill, drl);
            if (null != errorText) {
                result.setMessage(errorText);
                result.setSuccess(false);
                return result;
            }
            LOGGER.info("cancelDWaybillWithUser 取消知车系统运单关联: {}", waybill);
            waybill.setUserId(-1L);
            waybill.setWaybillStatus(DWaybillStatusEnum.FAILURE.getValue());
            this.dWaybillService.updateSelective(waybill);
            this.dWaybillStatusHistoryService.add(waybill.getId(), DWaybillStatusTypeEnum.PROCESS.getText(),
                    DWaybillStatusEnum.FAILURE.getText(), DWaybillStatusEnum.getByValue(waybill.getWaybillStatus()).getText(), 0L, "中联取消订单");
            /*// 从新初始化订单状态
            waybill.setUserId(0L);
			waybill.setWaybillStatus(DWaybillStatusEnum.SAVE.getValue());
			this.dWaybillService.updateSelective(waybill);
			this.dWaybillStatusHistoryService.add(waybill.getId(), DWaybillStatusTypeEnum.PROCESS.getText(),
					DWaybillStatusEnum.FAILURE.getText(), DWaybillStatusEnum.getByValue(waybill.getWaybillStatus()).getText(), 0L, "中联取消订单");
			// 放入队列
			TmsQueueOrderVo tqov = new TmsQueueOrderVo();
			tqov.setFrom(waybill.getDepartureCity());
			tqov.setTmsSerialNo(waybill.getOrderLineId().toString());
			tqov.setTo(waybill.getDestCity());
			tqov.setUrgent(waybill.getIsUrgent());
			tqov.setWaybillId(waybill.getId().toString());
			this.tmsQueueService.lPushOrder(tqov);*/
        } catch (Exception e) {
            LOGGER.error("cancelDWaybill error : {}", e);
            throw new BusinessException("取消失败！");
        }
        return result;
    }

    /**
     * 添加日志
     *
     * @param orderCode
     * @param cancelreason
     * @param cancelflag
     * @return
     */
    private DRequestLogs addLogs(String orderCode, String cancelreason, String cancelflag) {
        JSONObject j = new JSONObject();
        j.put("orderCode", orderCode);
        j.put("cancelflag", cancelflag);
        j.put("cancelreason", cancelreason);
        return this.tmsRequestLogsService.addLog(orderCode, DRequestTypeEnum.CANCEL.getValue(), j);
    }

    @Override
    public Result<String> receipt(HttpServletRequest request, String phone, String orderCodes) throws Exception {
        //验证用户
        Result<String> r = this.validationUser(request);
        if (!r.isSuccess()) {
            return r;
        }
        // 非空校验
        if (StringUtils.isBlank(phone) || StringUtils.isBlank(orderCodes)) {
            r.setMessage("手机号或订单号不可为空");
            r.setSuccess(false);
            return r;
        }
        // 获取司机用户信息
        SUser suser = this.userService.getByPhone(phone, UserTypeEnum.SEND_DRIVER.getValue());
        if (null == suser) {
            r.setMessage("获取用户信息异常");
            r.setSuccess(false);
            return r;
        }
        // 获取运单数据
        DWaybill dw = this.getByTmsOrderCode(orderCodes, true);
        if (null == dw) {
            r.setMessage("获取运单信息异常");
            r.setSuccess(false);
            return r;
        }
        // 调用回单接口
        int waybillStatus = dw.getWaybillStatus();
        if (!(waybillStatus == DWaybillStatusEnum.DEAL_CAR.getValue() || waybillStatus == DWaybillStatusEnum.EXCEPTION_CONFIRM.getValue())) {
            r.setMessage("运单当前不是交车状态，不可结算");
            r.setSuccess(false);
            return r;
        }
        // 检车回单记录
		/*TmsOrderCallHistoryExample toche = new TmsOrderCallHistoryExample();
		toche.createCriteria().andTmsUrlTypeEqualTo(TmsUrlTypeEnum.PULL_ORDER_CONFIRM.getValue())
				.andResultContentLikeInsensitive("%"+ orderCodes +"%");
		int count = this.tmsOrderCallHistoryMapper.countByExample(toche);
		if (count <= 0) {
			r.setMessage("暂未收到中联回单记录");
			r.setSuccess(false);
			return r;
		}*/
        // 修改状态
		/*DWaybill dwNew = new DWaybill();
		dwNew.setId(dw.getId());
		dwNew.setWaybillStatus(DWaybillStatusEnum.DEAL_CAR.getValue());
		this.dWaybillMapper.updateByPrimaryKeySelective(dwNew);*/
        // 调用结算
        this.orderService.confirmResult(dw.getId());
        r.setSuccess(true);
        return r;
    }

    /**
     * 获取运单对象
     *
     * @param orderCode     订单编号
     * @param isAssociation 是否关联用户
     * @return 运单对象
     */
    private DWaybill getByTmsOrderCode(String orderCode, boolean isAssociation) {
        DWaybillExample dwe = new DWaybillExample();
        DWaybillExample.Criteria c = dwe.createCriteria();
        c.andOrderCodeEqualTo(orderCode);
        if (isAssociation) {
            c.andUserIdGreaterThan(0L);
        }
        List<DWaybill> list = this.dWaybillMapper.selectByExample(dwe);
        return list.size() > 0 ? list.get(0) : null;
    }

    /**
     * 发送取消请求
     *
     * @param cancelreason 取消原因
     * @param cancelflag   取消方式
     * @param waybill      运单类型
     * @return 是否成功
     */
    private String cancelOrderByTms(String cancelreason, String cancelflag, DWaybill waybill, DRequestLogs drl) {
        String callResult = this.tmsOrderCallHistoryService.urlCall(TmsUrlConstant.PULL_ORDER_CANCEL, TmsUrlTypeEnum.PULL_ORDER_CANCEL.getValue(), this.getUrlCallParams(cancelreason, cancelflag, waybill.getOrderLineId(), waybill.getUserId()), 10000);
        LOGGER.info("TmsCustomerServiceImpl.cancelOrderByTms url call return : {}", callResult);
        if (StringUtils.isNotBlank(callResult)) {
            JSONObject result = JSONObject.parseObject(callResult);
            // 更新日志
            this.tmsRequestLogsService.addResultLog(drl.getId(), callResult);
            int errorCode = 0;
            String errorText = "调用中联取消接口失败";
            if (null == result) {
                LOGGER.info("------cancelOrderByTms-------调用中联接口取消订单失败-------------");
                return errorText;
            }
            if (result.getBooleanValue("success")) {
                LOGGER.info("------cancelOrderByTms-------调用中联接口取消订单成功-------------");
                errorCode = TmsCancelCodeEnum.OK.getValue();
            }
            TmsCancelCodeEnum tcce = TmsCancelCodeEnum.getByValue(result.getInteger("messagecode"));
            if (null != tcce) {
                errorCode = tcce.getValue();
                errorText = tcce.getText();
            }
            return errorCode == TmsCancelCodeEnum.OK.getValue() ? null : errorText;
        }
        return null;
    }

    /**
     * 获取用户信息
     *
     * @param cancelreason 取消原因
     * @param cancelflag   取消类型
     * @param orderilineid 流水号
     * @param userId       用户id
     * @return 参数结果集
     */
    private Map<String, Object> getUrlCallParams(String cancelreason, String cancelflag, Long orderilineid, Long userId) {
        Map<String, Object> result = new HashMap<>();
        SUser suser = this.userService.getById(userId);
        if (null != suser) {
            String phone = suser.getPhone();
            DUserExtExample duee = new DUserExtExample();
            duee.createCriteria().andPhoneEqualTo(phone);
            List<DUserExt> list = this.dUserExtMapper.selectByExample(duee);
            result.put("vccard", list.size() > 0 ? list.get(0).getIdNo() : "");
            result.put("orderilineid", orderilineid);
            result.put("cancelflag", cancelflag);
            result.put("cancelreason", cancelreason);
        }
        LOGGER.info("getUrlCallParams 调用中联取消接口参数 : {}", result.toString());
        return result;
    }

    /**
     * 判断客服信息是否可用
     *
     * @param request 请求
     * @return 可用状态；可用-true；不可用-false
     */
    private boolean isUsedCustomer(HttpServletRequest request) {
        String sessionId = request.getSession().getId();
        boolean rtnFlag = false;
        try {
            jedis = HYCUtils.getJedis();
            TmsCustomerVo tcv = this.getData(sessionId);
            if (null != tcv) {
                if (new Date().getTime() - tcv.getTime() > TIMER) {
                    this.remove(sessionId);
                    rtnFlag = false;
                } else {
                    rtnFlag = true;
                }
            }
        } finally {
            jedis.close();
        }
        return rtnFlag;
    }


    private Result<String> validationUser(HttpServletRequest request) {
        Result<String> result = new Result<>(true, "登录成功");
        if (!this.isUsedCustomer(request)) {
            result.setMessageCode(loginErrorCode);
            result.setSuccess(false);
            result.setMessage("登录信息验证失败");
            return result;
        }
        return result;
    }

    @Override
    public Result<String> openAccount(HttpServletRequest request, String phone) {
        Result<String> result = validationUser(request);
        if (!result.isSuccess()) {
            return result;
        }
        return this.getUserService().openAccount(phone);
    }

    @Override
    public Result<String> addDriver(TmsDriverVo tdv) {
        Result<String> r = new Result<>(false, "用户已存在");
        String phone = tdv.getPhone();
        SUser suser = this.userService.getByPhone(phone, Arrays.asList(UserTypeEnum.SEND_DRIVER.getValue(), UserTypeEnum.CONSUMER_DRIVER.getValue()), false);
        if (null != suser) {
            return r;
        }
        // 添加d_user
        DUserExample due = new DUserExample();
        due.createCriteria().andLoginNameEqualTo(phone);
        int count = this.dUserMapper.countByExample(due);
        if (count > 0) {
            return r;
        }
        DUser du = this.addDUser(tdv);
        // 添加d_user_ext
        DUserExt duext = this.addDUserExt(tdv, du);
        // 添加d_user_license
        this.addDUserLicense(tdv, du);
        // 添加s_user
        this.assemblySUser(du, duext, tdv);
        r.setMessage(null);
        r.setSuccess(true);
        return r;
    }

    @Override
    public Result<List<BLicenseType>> getBLicenseList() {
        Result<List<BLicenseType>> r = new Result<>(true);
        r.setData(this.bLicenseTypeMapper.selectByExample(null));
        return r;
    }

    /**
     * 组装s用户信息
     *
     * @param du  d用户
     * @param due d用户扩展信息
     * @param tdv 数据
     */
    private void assemblySUser(DUser du, DUserExt due, TmsDriverVo tdv) {
        SUser su = new SUser();
        su.setBirthday(due.getBirthday());
        su.setEnable(AvailableEnum.F.getValue());
        su.setGender(due.getGender());
        su.setName(due.getUserName());
        su.setPhone(due.getPhone());
        su.setRealName(due.getRealName());
        su.setUserType(UserTypeEnum.SEND_DRIVER.getValue());
        su.setPwd(this.passwordEncoder.encodePassword(default_password, jwtAuthenticationFilter.getSecureKey()));
        su.setUserStatus(20);
        this.sUserMapper.insert(su);
    }

    /**
     * 添加驾照信息
     *
     * @param tdv 司机表单对象
     * @param du  用户对象
     */
    private void addDUserLicense(TmsDriverVo tdv, DUser du) {
        DUserLicense dul = new DUserLicense();
        dul.setCreateTime(new Date());
        dul.setReceiveTime(DateUtils.StrToDate(tdv.getLicenseDate(), DateUtils.FORMAT_DATETIME));
        dul.setUserId(du.getId());
        BLicenseTypeExample bte = new BLicenseTypeExample();
        String licenseName = tdv.getLicense().toUpperCase();
        bte.createCriteria().andLicenseNameEqualTo(licenseName).andLicenseTypeEqualTo(licenseName);
        List<BLicenseType> licenseList = this.bLicenseTypeMapper.selectByExample(bte);
        BLicenseType blt = licenseList.size() > 0 ? licenseList.get(0) : null;
        if (null == blt) {
            throw new BusinessException("获取用户证件类型失败");
        }
        dul.setLicenseDept("");
        dul.setLicenseName(blt.getLicenseName());
        dul.setSysLicenseId(blt.getId());
        this.dUserLicenseMapper.insert(dul);
    }

    /**
     * 添加d用户扩展
     *
     * @param tdv 用户表单
     * @param du  用户对象
     */
    private DUserExt addDUserExt(TmsDriverVo tdv, DUser du) {
        DUserExtExample duee = new DUserExtExample();
        duee.createCriteria().andIdNoEqualTo(tdv.getIdCard());
        List<DUserExt> list = this.dUserExtMapper.selectByExample(duee);
        if (list.size() > 0) {
            throw new BusinessException("此身份证信息已存在");
        }
        DUserExt due = new DUserExt();
        due.setBirthday(DateUtils.StrToDate(tdv.getBirthday(), DateUtils.FORMAT_DATETIME));
        due.setCreateTime(new Date());
        due.setGender(GenderEnum.T.getValue());
        due.setHomeAddress(tdv.getAddress());
        due.setIdNo(tdv.getIdCard().toUpperCase());
        due.setPhone(tdv.getPhone());
        due.setRealName(tdv.getName());
        due.setTmsDriverNo(tdv.getLicenseCode().toUpperCase());
        due.setUserId(du.getId());
        due.setUserName(tdv.getName());
        this.dUserExtMapper.insert(due);
        return due;
    }

    /**
     * 添加tms用户
     *
     * @param tdv 用户表单
     */
    private DUser addDUser(TmsDriverVo tdv) {
        Date d = new Date();
        DUser du = new DUser();
        du.setCreateTime(d);
        du.setEnable(true);
        du.setLastLoginTime(d);
        du.setLoginName(tdv.getPhone());
        du.setLoginTime(d);
        du.setPwd(this.passwordEncoder.encodePassword(default_password, jwtAuthenticationFilter.getSecureKey()));
        du.setType(TmsUserTypeEnum.DRIVER.getValue());
        this.dUserMapper.insert(du);
        return du;
    }

    @Override
    public Result<String> exchangeAccount(HttpServletRequest request, String idCard, String phone) {
        Result<String> result = validationUser(request);
        if (!result.isSuccess()) {
            return result;
        }
        if (StringUtils.isBlank(idCard) || StringUtils.isBlank(phone)) {
            result.setSuccess(false);
            result.setMessage("身份证号或手机号不可为空");
            return result;
        }
        return this.executionExchangeUser(idCard, phone);
    }

    /**
     * 修改用户
     *
     * @param idCard 身份证号
     * @param phone  手机号
     * @return 结果集
     */
    private Result<String> executionExchangeUser(String idCard, String phone) {
        Result<String> r = new Result<>(false);
        // 获取用户扩展信息
        DUserExtExample duee = new DUserExtExample();
        duee.createCriteria().andIdNoEqualTo(idCard);
        List<DUserExt> list = this.dUserExtMapper.selectByExample(duee);
        if (list.size() != 1) {
            r.setMessage("用户不存在");
            return r;
        }
        DUserExt dUserExt = list.get(0);
        String oldPhone = dUserExt.getPhone();
        // 获取用户信息
        DUser du = this.dUserMapper.selectByPrimaryKey(dUserExt.getUserId());
        if (null == du) {
            r.setMessage("用户不存在");
            return r;
        }
        // 获取系统用户信息
        SUserExample sue = new SUserExample();
        sue.createCriteria().andPhoneEqualTo(oldPhone).andUserTypeEqualTo(UserTypeEnum.SEND_DRIVER.getValue()).andEnableEqualTo(AvailableEnum.F.getValue());
        List<SUser> sUserList = this.sUserMapper.selectByExample(sue);
        if (sUserList.size() != 1) {
            r.setMessage("用户不存在或已开通");
            return r;
        }
        SUser su = sUserList.get(0);

        // 修改信息 dUser
        du.setLoginName(phone);
        du.setEnable(true);
        this.dUserMapper.updateByPrimaryKeySelective(du);
        // 修改信息 dUserExt
        dUserExt.setPhone(phone);
        this.dUserExtMapper.updateByPrimaryKeySelective(dUserExt);
        // 修改信息 sUser
        su.setEnable(AvailableEnum.T.getValue());
        su.setPhone(phone);
        su.setPwd(su.getPwd().replaceAll("==", "00"));
        this.sUserMapper.updateByPrimaryKeySelective(su);

        r.setSuccess(true);
        return r;
    }

    @Override
    public Result<String> getAccountByIdNo(HttpServletRequest request, String idCard) {
        Result<String> r = validationUser(request);
        if (!r.isSuccess()) {
            return r;
        }
        // 获取用户扩展信息
        DUserExtExample duee = new DUserExtExample();
        duee.createCriteria().andIdNoEqualTo(idCard);
        List<DUserExt> list = this.dUserExtMapper.selectByExample(duee);
        if (list.size() != 1) {
            r.setMessage("用户不存在");
            return r;
        }
        DUserExt dUserExt = list.get(0);
        r.setData(dUserExt.getRealName());
        r.setSuccess(true);
        return r;
    }

    @Override
    public Result<String> disableAccount(HttpServletRequest request, String phone) {
        Result<String> result = validationUser(request);
        if (!result.isSuccess()) {
            return result;
        }
        return this.getUserService().disableAccount(phone);
    }

    @Override
    public Result<String> topOrder(HttpServletRequest request, String orderCodes) throws Exception {
        //验证用户
        Result<String> validationUser = this.validationUser(request);
        if (!validationUser.isSuccess()) {
            return validationUser;
        }
        return this.tmsQueueService.resetQueueOrder(orderCodes);
    }

    @Override
    public Result<String> exceptionConfirmResult(HttpServletRequest request, String orderCodes) {
        // 验证用户
        Result<String> r = this.validationUser(request);
        if (!r.isSuccess()) {
            return r;
        }
        // 判断非空
        if (StringUtils.isBlank(orderCodes)) {
            r.setMessage("订单不可为空");
            r.setSuccess(false);
            return r;
        }
        // 获取已交车订单数据
        List<String> orderCodeList = this.getOrderCodeList(orderCodes);
        DWaybillExample dwe = new DWaybillExample();
        dwe.createCriteria().andUserIdGreaterThan(0L).andWaybillStatusEqualTo(DWaybillStatusEnum.DEAL_CAR.getValue()).andOrderCodeIn(orderCodeList);
        List<DWaybill> dList = this.dWaybillMapper.selectByExample(dwe);
        if (dList.size() <= 0) {
            r.setMessage("订单不存在或不是交车状态");
            r.setSuccess(false);
            return r;
        }
        StringBuffer sb = new StringBuffer("");
        for (DWaybill wd : dList) {
            wd.setWaybillStatus(DWaybillStatusEnum.EXCEPTION_CONFIRM.getValue());
            this.dWaybillMapper.updateByPrimaryKeySelective(wd);
            // 添加日志
            this.dWaybillStatusHistoryService.add(wd.getId(), DWaybillStatusTypeEnum.PROCESS.getText(), DWaybillStatusEnum.DEAL_CAR.getText(), DWaybillStatusEnum.getByValue(wd.getWaybillStatus()).getText(), 0L, "异常回单");
            sb.append(wd.getOrderCode()).append(", ");
        }
        String sbStr = sb.toString();
        if (sbStr.length() > 0) {
            sbStr = sbStr.substring(0, sbStr.length() - 2);
        }
        r.setData(sbStr);
        r.setSuccess(true);
        return r;
    }

    /**
     * 获取订单列表
     *
     * @param orderCodes 订单号
     * @return 结果集
     */
    private List<String> getOrderCodeList(String orderCodes) {
        List<String> list = new ArrayList<>();
        orderCodes = orderCodes.replaceAll("，", ",");
        String[] orderCodeArray = orderCodes.split(",");
        for (String s : orderCodeArray) {
            list.add(s.trim());
        }
        return list;
    }

    @Override
    public Result<Object> queueOrderList(HttpServletRequest request) throws Exception {
        Result<Object> r = new Result<>(true);
        // 验证用户
        Result<String> check = this.validationUser(request);
        if (!check.isSuccess()) {
            r.setSuccess(false);
            r.setMessage("登录用户信息验证失败");
            return r;
        }
        r.setData(this.getTmsQuequOrderList());
        return r;
    }

    /**
     * 获取队列订单自定义视图数据
     *
     * @return 结果集
     */
    private List<Map<String, Object>> getTmsQuequOrderList() throws Exception {
        List<Map<String, Object>> list = new ArrayList<>();
        List<DWaybill> data = this.tmsQueueService.queueOrderList().getData();
        StringBuffer sb = new StringBuffer("");
        if (null != data) {
            for (DWaybill wd : data) {
                sb.append("'").append(wd.getOrderCode()).append("',");
            }
        }
        String sbStr = sb.toString();
        if (sbStr.endsWith(",")) {
            sbStr = sbStr.substring(0, sbStr.length() - 1);
            StringBuffer sql = new StringBuffer("");
            sql.append("select a.order_code as orderCode, a.departure_city as departureCity, a.dest_province as destProvince, a.dest_city as destCity, b.vcvin, b.vcstyleno, b.vcstylename")
                    .append(" from d_waybill a, tms_order b where a.tms_order_id = b.id and a.order_code in(").append(sbStr).append(")");
            list = JdbcTemplateUtils.getJdbcTemplate().queryForList(sql.toString());
        }
        return list;
    }

    @Override
    public Result<Object> queueDriverList(HttpServletRequest request) throws Exception {
        Result<Object> r = new Result<>(true);
        // 验证用户
        Result<String> check = this.validationUser(request);
        if (!check.isSuccess()) {
            r.setSuccess(false);
            r.setMessage("登录用户信息验证失败");
            return r;
        }
        r.setData(this.tmsQueueService.queueDriverList().getData());
        return r;
    }

    /**
     * 追加用户到session
     *
     * @param sessionId sessionid
     */
    private void append(String sessionId) {
        this.remove(sessionId);
        jedis.rpush(TMS_CUSTOMER_LOGIN_LIST, JSONObject.toJSONString(new TmsCustomerVo(sessionId, new Date().getTime())));
    }

    /**
     * 移除用户信息
     *
     * @param sessionId session
     */
    private void remove(String sessionId) {
        TmsCustomerVo tcv = this.getData(sessionId);
        if (null != tcv) {
            jedis.lrem(TMS_CUSTOMER_LOGIN_LIST, 1L, JSONObject.toJSONString(tcv));
        }
    }

    /**
     * 获取用户信息
     *
     * @param sessionId sessionId
     * @return 用户对象
     */
    private TmsCustomerVo getData(String sessionId) {
        long lengthVal = jedis.llen(TMS_CUSTOMER_LOGIN_LIST);
        for (long i = 0; i < lengthVal; i++) {
            String indexVal = jedis.lindex(TMS_CUSTOMER_LOGIN_LIST, i);
            if (StringUtils.isNotBlank(indexVal) && indexVal.contains(sessionId)) {
                return JSONObject.parseObject(indexVal, TmsCustomerVo.class);
            }
        }
        return null;
    }

    @Override
    public Result<Object> calcenList(HttpServletRequest request, String orderCode) {
        Result<Object> r = new Result<>(true);
        // 验证用户
        Result<String> check = this.validationUser(request);
        if (!check.isSuccess()) {
            r.setSuccess(false);
            r.setMessage("登录用户信息验证失败");
            return r;
        }
        r.setData(this.parseCalcenList(this.getCalcenListBySql(orderCode)));
        return r;
    }

    /**
     * 解析退单列表记录
     *
     * @param list 数据
     * @return 结果集
     */
    private List<Object> parseCalcenList(List<Map<String, Object>> list) {
        List<Object> rtnList = new ArrayList<>();
        if (null != list) {
            for (Map<String, Object> map : list) {
                JSONObject j = new JSONObject();
                j.put("orderCode", map.get("order_code"));
                j.put("outsetTime", map.get("outset_time"));
                j.put("createTime", map.get("result_time"));
                Object requestObj = map.get("request");
                String request = null == requestObj ? "" : requestObj.toString();
                // 解析参数
                if (StringUtils.isNotBlank(request)) {
                    JSONObject requestJSON = JSONObject.parseObject(request);
                    TmsOrderCancelEnum toce = TmsOrderCancelEnum.getByValue(requestJSON.getInteger("cancelflag"));
                    if (null != toce) {
                        j.put("type", toce.getText());
                    }
                    j.put("reason", requestJSON.getString("cancelreason"));
                }
                // 解析返回结果
                Object resultObj = map.get("result");
                String result = null == resultObj ? "" : resultObj.toString();
                if (StringUtils.isNotBlank(result)) {
                    JSONObject resultJSON = JSONObject.parseObject(result);
                    if (resultJSON.getBooleanValue("success")) {
                        j.put("result", "退单成功");
                    } else {
                        TmsCancelCodeEnum tcce = TmsCancelCodeEnum.getByValue(resultJSON.getInteger("messagecode"));
                        if (null != tcce) {
                            j.put("result", tcce.getText());
                        }
                    }
                }
                rtnList.add(j);
            }
        }
        return rtnList;
    }

    /**
     * 获取退单列表
     *
     * @param orderCode
     * @return
     */
    private List<Map<String, Object>> getCalcenListBySql(String orderCode) {
        String sql = "SELECT a.order_code, a.outset_time, b.id, b.type, b.request, b.create_time, b.result, b.result_time FROM (SELECT * FROM d_waybill WHERE user_id = -1 AND waybill_status = " +
                +DWaybillStatusEnum.FAILURE.getValue() + (StringUtils.isNotBlank(orderCode) && !orderCode.equals("null") ? " AND order_code = '" + orderCode + "'" : "")
                + ") a LEFT JOIN (SELECT * FROM d_request_logs WHERE type = " + DRequestTypeEnum.CANCEL.getValue()
                + ") b ON a.order_code = b.order_code";
        return JdbcTemplateUtils.getJdbcTemplate().queryForList(sql);
    }

    @Override
    public Result<String> addOrderToRedis(HttpServletRequest request, String orderCode) throws Exception {
        LOGGER.info("addOrderToRedis params orderCode: {}", orderCode);
        //验证用户
        Result<String> validationUser = this.validationUser(request);
        if (!validationUser.isSuccess()) {
            return validationUser;
        }
        Result<String> result = new Result<>(true, null, "订单重新入队成功！");

        DWaybill dWaybill = dWaybillService.getByTmsOrderCode(orderCode);
        if (null != dWaybill) {

            // 修改订单状态
            DWaybill updateDWaybill = new DWaybill();
            updateDWaybill.setId(dWaybill.getId());
            updateDWaybill.setUserId(0L);
            updateDWaybill.setWaybillStatus(DWaybillStatusEnum.SAVE.getValue());
            dWaybillService.updateSelective(updateDWaybill);
        }

        //20170328 liangpeng 去掉订单回到redis操作，原因是会影响派单顺序，造成后排队司机先接单。
        /*try {
            // 放入队列
            TmsQueueOrderVo tqov = new TmsQueueOrderVo();
            tqov.setFrom(dWaybill.getDepartureCity());
            tqov.setTmsSerialNo(dWaybill.getOrderLineId().toString());
            tqov.setTo(dWaybill.getDestCity());
            tqov.setUrgent(dWaybill.getIsUrgent());
            tqov.setWaybillId(dWaybill.getId().toString());
            this.tmsQueueService.appendOrder(tqov);
        } catch (Exception e) {
            LOGGER.error("addOrderToRedis error: {}", e);
            throw new BusinessException("订单重新入队异常");
        }*/
        return result;
    }

    @Override
    public Result<Object> queryOrder(HttpServletRequest request, String orderCode) {
        LOGGER.info("queryOrder params orderCode: {}", orderCode);
        Result<Object> result = new Result<>(true, null, "订单加载成功");
        if (StringUtils.isBlank(orderCode)) {
            LOGGER.info("orderCode is not null");
            throw new BusinessException("订单号不能为空");
        }
        DWaybillExample example = new DWaybillExample();
        example.createCriteria().andOrderCodeEqualTo(orderCode);
        List<DWaybill> dWaybills = dWaybillMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(dWaybills)) {
            DWaybill dWaybill = dWaybills.get(0);
            DWaybillDetailVo vo = new DWaybillDetailVo();
            vo.setId(dWaybill.getUserId());
            vo.setStatus(dWaybill.getWaybillStatus());
            vo.setOrderCode(orderCode);
            vo.setDepartProvince(dWaybill.getDepartureProvince());
            vo.setDepartCity(dWaybill.getDepartureCity());
            vo.setArrivalProvince(dWaybill.getDestProvince());
            vo.setArrivalCity(dWaybill.getDestCity());
            result.setData(vo);
        }
        return result;
    }

    @Override
    public Result<Object> userList(HttpServletRequest request, String phone) {
        LOGGER.info("TmsCustomerServiceImpl.userList params phone: {}", phone);
        Result<Object> result = new Result<>(true, null, "查询成功");
        try {
            List<DUserVo> lists = dUserViewMapper.selectByCondition(phone);
            if (CollectionUtils.isNotEmpty(lists)) {
                DUserVo dUserVo = lists.get(0);
                if (StringUtils.isNotBlank(dUserVo.getImage())) {
                    String treatMethod = "?imageView2/1/w/220/h/240";
                    dUserVo.setImage(QiniuUtils.generateDownloadTicket(dUserVo.getImage(), treatMethod));
                }
                List<DUserVo> list = new ArrayList<>();
                list.add(dUserVo);
                result.setData(list);
            }
        } catch (Exception e) {
            LOGGER.error("TmsCustomerServiceImpl.userList error: {}", e);
            throw new BusinessException("查询异常");
        }
        return result;
    }

    /**
     * 自动任务取消中联订单
     */
    public Result<String> cancelTMSbyIDCard(DWaybill waybill) {
        Result<String> result = new Result<>(true, "取消成功！");
        // 调用中联接口
        String cancelreason = "推送TMS出现问题，撤销TMS订单";
        String cancelflag = "2";
        // 添加日志
        DRequestLogs drl = this.addLogs(waybill.getOrderCode(), cancelreason, cancelflag);
        String errorText = this.cancelOrderByTms(cancelreason, "2", waybill, drl);
        if (null != errorText) {
            result.setMessage(errorText);
            result.setSuccess(false);
            return result;
        }
        LOGGER.info("cancelDWaybillWithUser 取消知车系统运单关联: {}", waybill.toString());

        this.dWaybillStatusHistoryService.add(waybill.getId(), DWaybillStatusTypeEnum.PROCESS.getText(),
                DWaybillStatusEnum.FAILURE.getText(), DWaybillStatusEnum.getByValue(waybill.getWaybillStatus()).getText(), 0L, "中联取消订单");
        return result;
    }
}
